﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Configuration;
using System.Data;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Net;
using System.ServiceProcess;
using System.Text;
using System.Threading.Tasks;
using FastDFS.Client;
using FileConvert;
using log4net;

namespace WindowsService1
{
    public partial class Service1 : ServiceBase
    {
        /// <summary>    
        /// 全局锁
        /// </summary>
        private static object objLock = new object();
        /// <summary>
        /// 日志对象
        /// </summary>
        private ILog _log;
        /// <summary>
        /// 从DFS下载文件后保存的地址
        /// </summary>
        string fileSavePath = ConfigurationManager.AppSettings["OldPath"].ToString();
        /// <summary>
        /// 转码后的文件地址
        /// </summary>
        string convertFileSavePath = ConfigurationManager.AppSettings["SavePath"].ToString();
        public Service1()
        {
            log4net.Config.XmlConfigurator.Configure();
            _log = LogManager.GetLogger(GetType());
            InitializeComponent();
        }

        protected override void OnStart(string[] args)
        {
            this.timer1 = new System.Timers.Timer();
            this.timer1.Start();
            this.timer1.Interval = 1000;
            this.timer1.Elapsed += new System.Timers.ElapsedEventHandler(this.timer1_Elapsed);
        }

        protected override void OnStop()
        {
            this.timer1.Stop();
        }

        private void timer1_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
        {
            /* 队列使用说明
             * 如果是及时转换IsImmediately=1，然后在视频转换完成后， 
             * 使用LeftPush向队列首部添加，返回使用RightPush向队列尾部添加
             * */

            //if (Process.GetProcessesByName("ffmpeg") != null
            //   && Process.GetProcessesByName("ffmpeg").Length == 0) //同时跑一个进程
            lock (objLock)
            {
                #region 从文件转换队列中得到要转换的对象
                var entity = new ScheduleToRedis();
                using (var redisClient = Redis.Client.RedisManager.GetClient())
                {
                    using (var redisList = redisClient.GetTypedClient<ScheduleToRedis>())
                    {
                        entity = redisList.Lists["FileConvertQueue"].Dequeue();
                    }
                }
                #endregion

                if (entity != null)
                {
                    _log.Info("从队列里取出了一个对象,对象名:" + entity.FileName);

                    #region 视频转换服务

                    _log.Info("begin download files:" + entity.LocalPath);
                    FileDownLoad(entity);
                    _log.Info("complet download files:" + entity.LocalPath);

                    _log.Info("begin Convertfiles:" + entity.FileName);
                    MessageEntity message = ConvertFile(entity);
                    _log.Info("complete Convertfiles:" + entity.FileName);

                    var uploadDFSmessage = FileUpLoad(entity.DFSGroupName, message);//上传到ＤＦＳ之后的文件名

                    #region 得到文件大小，然后删除文件
                    int fileSize = 0;
                    try
                    {
                        FileInfo fileInfo = new FileInfo(message.FileName);
                        fileSize = Convert.ToInt32(fileInfo.Length);
                        File.Delete(message.FileName);
                        File.Delete(fileSavePath + entity.FileName);
                        File.Delete(message.FileName.Substring(0, message.FileName.LastIndexOf(".")) + "_Big.jpg");
                        File.Delete(message.FileName.Substring(0, message.FileName.LastIndexOf(".")) + "_Small.jpg");
                        _log.Info("得到文件大小，然后删除文件");
                    }
                    catch (Exception ex)
                    {

                        _log.Fatal("得到文件大小，然后删除文件出错，信息：" + ex.Message);
                    }

                    #endregion

                    #region 为回调队列赋值

                    #endregion

                    #region 根据entity.IsImmediately判断写回调队列的方式
                    _log.Info("回调开始");

                    _log.Info("回调结束");
                    #endregion

                    _log.Info("任务完成\r\n");

                    #endregion
                }

            }

        }

        #region 文件下载，文件上传，文件传码
        /// <summary>
        /// 文件下载　
        /// </summary>
        /// <param name="entity"></param>
        void FileDownLoad(ScheduleToRedis entity)
        {
            var node = FastDFSClient.GetStorageNode(entity.DFSGroupName);
            #region socket协议下载
            //var result = new TranscodingToSchedule();
            //#region  从FastDFS中下载文件
            //FDFSFileInfo fileInfo = FastDFSClient.GetFileInfo(node, entity.LocalPath);
            //if (fileInfo.FileSize >= 1024)
            //{
            //    FileStream fs = new FileStream(fileSavePath + entity.FileName, FileMode.OpenOrCreate, FileAccess.Write);
            //    long offset = 0;
            //    long len = 1024 * 100;
            //    while (len > 0)
            //    {
            //        byte[] buffer = new byte[len];
            //        buffer = FastDFSClient.DownloadFile(node, entity.LocalPath, offset, len);
            //        fs.Write(buffer, 0, int.Parse(len.ToString()));
            //        fs.Flush();
            //        offset = offset + len;
            //        len = (fileInfo.FileSize - offset) >= 1024 ? 1024 : (fileInfo.FileSize - offset);
            //    }
            //    fs.Close();
            //}
            //else//如果文件大小小小于100KB  直接写入文件
            //{
            //    byte[] buffer = new byte[fileInfo.FileSize];
            //    buffer = FastDFSClient.DownloadFile(node, entity.LocalPath);
            //    FileStream fs = new FileStream(fileSavePath + entity.FileName, FileMode.OpenOrCreate, FileAccess.Write);
            //    fs.Write(buffer, 0, buffer.Length);
            //    fs.Flush();
            //    fs.Close();
            //}
            //#endregion
            #endregion

            WebClient web = new WebClient();
            web.DownloadFile(string.Format("http://{0}/{1}/{2}", entity.DFSHost, entity.DFSGroupName, entity.LocalPath), fileSavePath + entity.FileName);
        }
        /// <summary>
        /// 文件上传
        /// </summary>
        /// <param name="entity"></param>
        MessageEntity FileUpLoad(string groupName, MessageEntity message)
        {
            var node = FastDFSClient.GetStorageNode(groupName);
            string fileName = null;
            string bigImage = null;
            string smallImage = null;
            byte[] content = null;
            if (File.Exists(message.FileName))
            {
                using (FileStream streamUpload = new FileStream(message.FileName, FileMode.Open))
                {
                    using (BinaryReader reader = new BinaryReader(streamUpload))
                    {
                        content = reader.ReadBytes((int)streamUpload.Length);
                    }
                    fileName = FastDFSClient.UploadFile(node, content, message.ExtName.Substring(1));
                }
                if (File.Exists(message.BigImagePath))
                {
                    #region 上传图片
                    using (FileStream streamUpload = new FileStream(message.BigImagePath, FileMode.Open))
                    {
                        using (BinaryReader reader = new BinaryReader(streamUpload))
                        {
                            content = reader.ReadBytes((int)streamUpload.Length);
                        }
                        bigImage = FastDFSClient.UploadFile(node, content, "jpg");
                    }

                    using (FileStream streamUpload = new FileStream(message.SmallImagePath, FileMode.Open))
                    {
                        using (BinaryReader reader = new BinaryReader(streamUpload))
                        {
                            content = reader.ReadBytes((int)streamUpload.Length);
                        }
                        smallImage = FastDFSClient.UploadFile(node, content, "jpg");
                    }
                    #endregion
                }
            }
            return new MessageEntity
            {
                Result = 1,
                FileName = fileName,
                BigImagePath = bigImage,
                SmallImagePath = smallImage,
            };
        }
        /// <summary>
        /// 文件转码
        /// </summary>
        /// <param name="entity"></param>
        MessageEntity ConvertFile(ScheduleToRedis entity)
        {
            return new FileConvertFactory().CreateFileConvert(entity.DestFileType ?? "Mp4").Convert(entity.FileName, true);
        }
        #endregion
    }
}
